iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 21
0
自我挑戰組

Kotlin and Android 30 days系列 第 21

Day 21 MediaPlayer/MediaRecorder (下)

  • 分享至 

  • xImage
  •  

接續上篇對播放器的操作,這篇要加上動畫效果和錄音的部分。

顯示動畫

這邊使用到以前使用過的 ObjectAnimator 來達成效果
以下為設定

  • rotationY 表示繞著 Y 軸旋轉
  • 0.0f, 360.0f 表示從 0 度轉到 360 度
  • duration 表示完成一次動畫需要幾毫秒
  • repeatCount 表示重複幾次,型別為 Int,可以使用 ValueAnimator.INFINITE 來表示無限循環
animator = ObjectAnimator.ofFloat(
        imageView,
        "rotationY",
        0.0f, 360.0f
    )
    animator.duration = 4000
    animator.repeatCount = ValueAnimator.INFINITE

接著要再開始播放音樂的時候啟動動畫
因為播放和暫停的按鈕是同一顆,所以我們要寫個判斷去執行開始、暫停、繼續等動作

when {
    animator.isPaused -> {
        animator.resume()
    }
    animator.isRunning -> {
        animator.pause()
    }
    else -> {
        animator.start()
    }
}

停止的時候使用 end()

animator.end()

錄音

<uses-permission android:name="android.permission.RECORD_AUDIO" />
fun checkPermission() {
    //檢查硬體設備
    if (!activity.packageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
        Toast.makeText(activity, "Your device doesn't have a microphone", Toast.LENGTH_LONG).show()
        return
    }

    //檢查錄音權限
    if (ActivityCompat.checkSelfPermission(
            activity,
            Manifest.permission.RECORD_AUDIO
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.RECORD_AUDIO), 0)
    }
}

建立空白音訊檔案

首先要建立一個空白檔案對象給 MediaPlayer 寫入。
使用 activity.applicationContext.filesDir.path 得到內部儲存空間的檔案目錄
createTempFile 方法的第一個參數為檔案名稱的前綴,第二個參數為後綴,也就是檔案類型

private fun buildMediaFile() {
    val file = File(activity.applicationContext.filesDir.path)

    try {
        soundFile = File.createTempFile("test", ".3gp", file)

        println("created file $soundFile")

    } catch (ex: Exception) {
        println("Setup sound File\", \"failed ${ex.message}")
    }
}

開始錄音

setAudioEncoder() 方法要放在 setOutputFormat() 跟 prepare() 中間

fun startRecord() {
    buildMediaFile()
    recorder = MediaRecorder()
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC)
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)

    recorder.setOutputFile(soundFile?.absolutePath)
    recorder.prepare()
    recorder.start()

    Toast.makeText(activity, "Start recording", Toast.LENGTH_SHORT).show()
}

停止錄音

fun stopRecord() {
    recorder.stop()
    recorder.release()
    Toast.makeText(activity, "Record finished", Toast.LENGTH_SHORT).show()
}

停止錄音後,可以看到檔案儲存至內部儲存空間,檔名除了建立空白檔案時建立的前綴和後綴外,中間還多了一串亂數號碼。

播放錄音

最後快速建立一個 MediaPlayer 來播放音訊,路徑使用 soundFile.absolutePath 來取得。

fun playRecord() {
    val player = MediaPlayer()
    player.setDataSource(soundFile.absolutePath)
    player.prepare()
    player.start()
}

上一篇
Day 20 MediaPlayer/MediaRecorder (上)
下一篇
Day 22 ActivityTransition
系列文
Kotlin and Android 30 days30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言